package _Pan3D.particle
{
	import _Pan3D.base.Camera3D;
	import _Pan3D.base.Focus3D;
	import _Pan3D.display3D.interfaces.IDisplay3D;
	import _Pan3D.particle.interfaces.IParticle;
	
	import _me.Scene_data;
	
	import flash.display.Bitmap;
	import flash.display.BitmapData;
	import flash.display3D.Context3D;
	import flash.display3D.Context3DProgramType;
	import flash.display3D.Context3DTextureFormat;
	import flash.display3D.Context3DVertexBufferFormat;
	import flash.display3D.IndexBuffer3D;
	import flash.display3D.Program3D;
	import flash.display3D.VertexBuffer3D;
	import flash.display3D.textures.Texture;
	import flash.geom.Matrix3D;
	import flash.geom.Vector3D;

	public class FireBall implements IParticle
	{
		protected var verterAry:Vector.<Number>;
		protected var verterAry2:Vector.<Number>;
		protected var indexAry:Vector.<uint>;
		
		protected var _context:Context3D;
		protected var verterBuffer:VertexBuffer3D;
		protected var verterBuffer2:VertexBuffer3D;
		protected var indexBuffer:IndexBuffer3D;
		protected var textureBuffer:Texture;
		
		private var modelMatix:Matrix3D;
		
		protected var modelMatrix:Matrix3D;
		protected var posMatrix:Matrix3D;
		
		protected var _x:Number = 0;
		protected var _y:Number = 0;
		protected var _z:Number = 0;
		
		protected var _vc:Vector.<Vector.<Number>>;
		
		public var speed:Number = 1;
		
		public var program:Program3D;
		
		public function FireBall(context:Context3D)
		{
			this._context = context;
			modelMatrix = new Matrix3D;
			posMatrix = new Matrix3D;
			colorVec = new Vector.<Number>();//[210/256,108/256,16/256,0]
			colorVec.push(210/256,108/256,16/256,0);
			_vc = new Vector.<Vector.<Number>>;
			init();
			//reSetState();
		}
		public var num:int = 20;
		public var xConfig:Number = 0;
		public var yConfig:Number = 10;
		public var zConfig:Number = 0;
		public var scConfig:Number = 0.5;
		public var colorVec:Vector.<Number>;
		public function init():void{
			verterAry = new Vector.<Number>;
			verterAry2 = new Vector.<Number>;
			indexAry = new Vector.<uint>;
			
			
			
			for(var j:int;j<num;j++){
				verterAry.push(-1,1,0,0,0);
				verterAry.push(1,1,0,1,0);
				verterAry.push(1,-1,0,1,1);
				verterAry.push(-1,-1,0,0,1);
				
				var tdel:Number = 12 + j;
				var vcnum:Vector.<Number> = new Vector.<Number>();
				_vc.push(vcnum);
				for(var i:int = 0;i<4;i++){
					verterAry2.push(tdel);
					vcnum.push(0);
				}
				//vcnum[3] = 1;
				
				var begin:int = j*4;
				indexAry.push(begin,begin+1,begin+2,begin,begin+2,begin+3);
			}
			
			upLoadToGpu();
		}
		
		[Embed(source="../_File/nijia2/lizhi/texture/fensanPic.jpg")]
		private var cls:Class;
		
		protected function upLoadToGpu():void{
			verterBuffer = _context.createVertexBuffer(4*num,5);
			verterBuffer.uploadFromVector(verterAry,0,verterAry.length/5);
			
			verterBuffer2 = _context.createVertexBuffer(4*num,1);
			verterBuffer2.uploadFromVector(verterAry2,0,verterAry2.length);
			
			indexBuffer = _context.createIndexBuffer(indexAry.length);
			indexBuffer.uploadFromVector(indexAry,0,indexAry.length);
			
			if(textureBuffer == null){
				var bitmapdata:BitmapData = Bitmap(new cls()).bitmapData;
				textureBuffer = this._context.createTexture(bitmapdata.width, bitmapdata.height, Context3DTextureFormat.BGRA, true);
				textureBuffer.uploadFromBitmapData(bitmapdata);
			}
		}
		
		public function uploadTexture(bitmapdata:BitmapData):void{
			textureBuffer = this._context.createTexture(bitmapdata.width, bitmapdata.height, Context3DTextureFormat.BGRA, true);
			textureBuffer.uploadFromBitmapData(bitmapdata);
		}
		private function addTexture(texture : Texture,obj:Object) : void {
			this.textureBuffer = texture;
		}
		public function update(t:Number=0):void{
			if(textureBuffer){
				_context.setProgram(this.program);
				setVc();
				setVa();
				resetVa();
			}
		}
		public function updateMatrix():void{
			modelMatrix.identity();
			modelMatrix.prepend(Scene_data.cam3D.cameraMatrix);
			modelMatrix.prepend(posMatrix);
		}
		private function setVa():void{
			_context.setVertexBufferAt(0,verterBuffer,0,Context3DVertexBufferFormat.FLOAT_3);
			_context.setVertexBufferAt(1,verterBuffer,3,Context3DVertexBufferFormat.FLOAT_2);
			_context.setVertexBufferAt(2,verterBuffer2,0,Context3DVertexBufferFormat.FLOAT_1);
			
			_context.setTextureAt(0,textureBuffer);
			_context.drawTriangles(indexBuffer,0,-1);
		}
		private function resetVa():void{
			_context.setVertexBufferAt(0,null);
			_context.setVertexBufferAt(1,null);
			_context.setVertexBufferAt(2,null);
			_context.setTextureAt(0,null);
		}
		protected var t:Number = -10;
		private var alpha:Number = 1;
		
		private var addStep:int;
		
		protected var tempM:Matrix3D=new Matrix3D;
		public function setVc():void{
			this.updateMatrix();
			
			var _Cam:Camera3D=Scene_data.cam3D;
			var _focus_3d:Focus3D=Scene_data.focus3D;
			
			_Cam.cameraMatrix.identity();
			_Cam.cameraMatrix.prependScale(1, _Cam.fovw / _Cam.fovh, 1);
			_Cam.cameraMatrix.prependTranslation(0, 0, -_Cam.distance);
			_Cam.cameraMatrix.prependTranslation(-_focus_3d.x, -_focus_3d.y, -_focus_3d.z);
			
			modelMatrix.identity();
			modelMatrix.prepend(_Cam.cameraMatrix);
			modelMatrix.prepend(posMatrix);
			
			tempM.identity();
			tempM.prependRotation(_Cam.angle_x  , Vector3D.X_AXIS);
			tempM.prependRotation(_Cam.angle_y  , Vector3D.Y_AXIS);
			
			_context.setProgramConstantsFromMatrix(Context3DProgramType.VERTEX, 4, modelMatrix, true);
			_context.setProgramConstantsFromMatrix(Context3DProgramType.VERTEX, 8, tempM, true);
			
			_context.setProgramConstantsFromVector(Context3DProgramType.FRAGMENT, 0, Vector.<Number>([-0.001, 0, 0, 1]));
			//_context.setProgramConstantsFromVector(Context3DProgramType.VERTEX, 12, Vector.<Number>([t, -0.001, -0.001, 0]));
			_context.setProgramConstantsFromVector(Context3DProgramType.FRAGMENT, 1, colorVec);
			
			for(var i:int;i<num;i++){
				_context.setProgramConstantsFromVector(Context3DProgramType.VERTEX, 12+i ,_vc[i]);
			}
			
//			t += 0.05;
//			alpha -= 0.0005;
//			_vc[0][0] = t;
//			_vc[0][3] = alpha;
//			trace(t)
//			
			for(i=0;i<num;i++){
				_vc[i][3] -= 0.05;
			}
			
			/*var index:int = getUnUse();
			if(index != -1){
				_vc[index][0] = (Scene_data.stage.mouseX/Scene_data.stage.stageWidth*2 - 1)*15;
				_vc[index][1] = -(Scene_data.stage.mouseY/Scene_data.stage.stageHeight*2 - 1)*15;
				_vc[index][3] = 1;
			}*/
			
			/*if(addStep >= 3){
				var index:int = getUnUse();
				if(index != -1){
					//_vc[index][0] = (Scene_data.stage.mouseX/Scene_data.stage.stageWidth*2 - 1)*15;
					_vc[index][1] = (Scene_data.stage.mouseY/Scene_data.stage.stageHeight*2 - 1)*15;
					_vc[index][3] = 1;
				}
				addStep = 0;
			}else{
				addStep++;
			}*/
			
			
		}
		
		public function setPos(xpos:Number,ypos:Number,zpos:Number):void{
			var index:int = getUnUse();
			if(index != -1){
				_vc[index][0] = xpos;
				_vc[index][1] = ypos;
				_vc[index][2] = zpos;
				_vc[index][3] = 1;
			}
			this.x = xpos;
			this.y = ypos;
			this.z = zpos;
		}
		
		private function getUnUse():int{
			for(var i:int;i<num;i++){
				if(_vc[i][3] <= 0){
					return i;
				}
			}
			return -1;
		}

		public function get x():Number
		{
			return _x;
		}
		
		public function set x(value:Number):void
		{
			_x = value;
			//updataPos();
		}
		
		public function get y():Number
		{
			return _y;
		}
		
		public function set y(value:Number):void
		{
			_y = value;
			//updataPos();
		}
		
		public function get z():Number
		{
			return _z;
		}
		
		public function set z(value:Number):void
		{
			_z = value;
			//updataPos();
		}
		private var _scale:Number = 1;
		public function updataPos():void{
			posMatrix.identity();
			//posMatrix.prependRotation(-90, new Vector3D(1, 0, 0));
			//posMatrix.prependTranslation(this._x, this._y, this._z);
			//posMatrix.prependScale(this._scale,this._scale,this._scale);
			//posMatrix.prependRotation(_rotationY , Vector3D.Y_AXIS);
		} 



	}
}